// Copyright 2024 The LUCI Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import Table from '@mui/material/Table';
import TableBody from '@mui/material/TableBody';
import TableCell from '@mui/material/TableCell';
import TableHead from '@mui/material/TableHead';
import TableRow from '@mui/material/TableRow';
import Typography from '@mui/material/Typography';

import CLList from '@/clusters/components/cl_list/cl_list';
import { ExoneratedTestVariantBranch } from '@/clusters/hooks/use_fetch_exonerated_test_variant_branches';
import {
  TestStabilityCriteria,
  TestVariantStabilityAnalysis_FailureRate_RecentVerdict,
} from '@/proto/go.chromium.org/luci/analysis/proto/v1/test_variants.pb';

import { ExplanationChip } from '../explanation_chip/explanation_chip';
import InvocationList from '../invocations_list/invocations_list';

interface Props {
  criteria: TestStabilityCriteria;
  testVariantBranch: ExoneratedTestVariantBranch;
}

const FailureCriteriaSection = ({ criteria, testVariantBranch }: Props) => {
  const runStats = (
    verdict: TestVariantStabilityAnalysis_FailureRate_RecentVerdict,
    isLast: boolean,
  ) => {
    let result = `${verdict.unexpectedRuns}/${verdict.totalRuns}`;
    if (verdict.changelists.length > 0) {
      // Some runs may have been truncated, as verdicts with CLs are allowed to contribute at most one run.
      result += '^';
    }
    if (isLast) {
      // Last verdict in the table may have had runs truncated due to limit of showing ten runs in the table.
      result += '*';
    }
    return result;
  };

  return (
    <>
      <Typography variant="h6">Purpose</Typography>
      <Typography paragraph>
        Exonerates test variants with a high failure rate (from approximately
        70% up to 100%), e.g. tests broken at tip-of-tree.
      </Typography>
      <Typography variant="h6">Definition</Typography>
      <Typography component="div" paragraph>
        <ExplanationChip
          value={testVariantBranch.failureRate.consecutiveUnexpectedTestRuns}
          threshold={criteria.failureRate?.consecutiveFailureThreshold || 0}
          text="Consecutive failing test runs"
          testId="consecutive_unexpected_verdict_count"
        ></ExplanationChip>
        &nbsp;OR&nbsp;
        <ExplanationChip
          value={testVariantBranch.failureRate.unexpectedTestRuns}
          threshold={criteria.failureRate?.failureThreshold || 0}
          text="Recent failing test runs"
          testId="unexpected_verdict_count"
        ></ExplanationChip>
        &nbsp;.
      </Typography>
      <Typography component="div">
        Where:
        <ul>
          <li>
            <strong>Test run</strong>: The result of executing a test in a
            swarming task. A test run is failing if all results obtained in the
            swarming task are failing (skips, execution errors and precluded
            results excepted).
          </li>
          <li>
            <strong>Recent test runs</strong>: The 10 most recent test runs for
            the test variant by commit position, filtered to:
            <ul>
              <li>
                at most one test run per distinct changelist tested (to avoid a
                single repeatedly retried bad changelist becoming
                overrepresented),
              </li>
              <li>
                exclude changelists generated by automation (e.g. autorollers),
                and
              </li>
              <li>
                exclude results from certain unusual CI processes, such as
                multi-changelist presubmit.
              </li>
            </ul>
          </li>
        </ul>
      </Typography>
      <Typography variant="h6">Recent test runs</Typography>
      <Table size="small">
        <TableHead>
          <TableRow>
            <TableCell>Commit Position</TableCell>
            <TableCell>Changelist and patchset</TableCell>
            <TableCell>Invocation(s)</TableCell>
            <TableCell>Failing Runs / Total Runs</TableCell>
          </TableRow>
        </TableHead>
        <TableBody>
          {testVariantBranch.failureRate.recentVerdicts.map(
            (
              verdict: TestVariantStabilityAnalysis_FailureRate_RecentVerdict,
              i: number,
            ) => {
              return (
                <TableRow key={verdict.invocations[0]}>
                  <TableCell>{verdict.position}</TableCell>
                  <TableCell>
                    <CLList changelists={verdict.changelists || []}></CLList>
                  </TableCell>
                  <TableCell>
                    <InvocationList
                      testId={testVariantBranch.testId}
                      invocations={verdict.invocations}
                    />
                  </TableCell>
                  <TableCell>
                    {runStats(
                      verdict,
                      i ===
                        testVariantBranch.failureRate.recentVerdicts.length - 1,
                    )}
                  </TableCell>
                </TableRow>
              );
            },
          )}
        </TableBody>
      </Table>
      <Typography component="div" paddingTop="1rem">
        ^ Some runs may be omitted as each changelist is limited to contributing
        at most one test run to the analysis.
      </Typography>
      <Typography component="div">
        * Some runs may be omitted as only the ten most recent test runs are
        included in the table.
      </Typography>
    </>
  );
};

export default FailureCriteriaSection;
